
package net.biaji.alephclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

/**
 * 图书管理员
 * 
 * @author biAji<biaji@biaji.net>
 */
public abstract class LibAgent {

    protected String baseurl;

    protected static String sessionID = "";

    protected String proxy = null;

    protected boolean isLogin = false;

    /**
     * 登录
     * 
     * @param name 所需用户名
     * @param password 所需密码
     * @return 登录结果
     */
    public abstract boolean login(String name, String password);

    /**
     * 判断是否已经登录
     * 
     * @return
     */
    public boolean isLogin() {
        return isLogin;
    }

    /**
     * 根据书名查找
     * 
     * @return 符合条件的书目列表
     */
    public abstract ArrayList<Book> searchByName(String bookName);

    /**
     * 根据命令查找：<br>
     * WRD - 任意字段的关键词<br>
     * WTI - 题名字段中的关键词<br>
     * WAU - 作者字段中的关键词<br>
     * WPU - 出版者字段中关键词<br>
     * WSU - 主题字段中的关键词<br>
     * WYR - 出版年字段中的关键词<br>
     * 
     * @param command 查询指令
     * @return 符合条件的书目列表
     */
    public abstract ArrayList<Book> searchByCommand(String command);

    /**
     * 获取一本书的详情
     * 
     * @param sn 系统号
     * @return 书目详情
     */
    public abstract Book getBook(String sn);

    /**
     * 获得当前在借的图书列表
     * 
     * @return
     */
    public abstract ArrayList<Book> getBookInPocket() throws NotLoginException;

    /**
     * 获取借阅历史
     * 
     * @return
     */
    public abstract ArrayList<Book> getHistory();

    /**
     * 预约<br>
     * 第一步：
     * 
     * <pre>
     * func=item-hold-request
     * doc_library=NJL50
     * adm_doc_number=001420544
     * item_sequence=000030
     * sub_library=MCBKL
     * type=
     * no_loaned=N
     * start_rec_key=
     * end_rec_key=
     * </pre>
     * 
     * <br>
     * 第二步：
     * 
     * <pre>
     * action="http://opac.jslib.org.cn:80/F/24X8FFCGF6TX748IT5EBK8P9XQDECI78TV3LQT13DBHHSQLA66-04715"
     *  "func"="item-hold-request-b"
     *  "doc_library"=NJL50
     *  "adm_doc_number"=001420544
     *  "item_sequence"=000030
     *  "bib_request"=N
     *  "from"="20121105"
     *  "to"="20130105"
     *  input type="image" 
     *              alt="确定" 
     *              src="http://opac.jslib.org.cn:80/exlibris/aleph/u20_1/alephe/www_f_chi/icon/f-go.gif" border=0>
     * </pre>
     * 
     * <br>
     * 第三步(预约应该已经完成)：
     * 
     * <pre>
     *       action="http://opac.jslib.org.cn:80/F/24X8FFCGF6TX748IT5EBK8P9XQDECI78TV3LQT13DBHHSQLA66-06543" 
     *  "func"="item-hold-request-c" 
     * "doc_library"=NJL50
     * "adm_doc_number"=001420544 
     * <input type="image" 
     *              alt="确定" 
     *              src="http://opac.jslib.org.cn:80/exlibris/aleph/u20_1/alephe/www_f_chi/icon/f-go.gif" border=0>
     * </pre>
     * 
     * @param docNum 预约的图书系统号
     */
    public abstract void reserve(String docNum) throws NotLoginException;

    /**
     * 续借
     * 
     * @param docNum 续借所用的图书系统号
     */
    public abstract void extend(String docNum) throws NotLoginException;

    /**
     * 获取页面
     * 
     * @param url
     * @return
     */
    protected String getContent(String url) {
        StringBuilder result = new StringBuilder();
        HttpURLConnection httpConnection = null;
        int retry = 0;
        boolean fetchSuccess = false;
        while (retry < 3 && !fetchSuccess) {
            try {
                System.out.println(url);
                URL urlImp = new URL(url);
                if (this.proxy == null)
                    httpConnection = (HttpURLConnection) urlImp.openConnection();
                else
                    httpConnection = (HttpURLConnection) urlImp.openConnection(new Proxy(
                            Proxy.Type.HTTP, new InetSocketAddress(proxy, 80)));
                BufferedReader breader;
                if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    breader = new BufferedReader(new InputStreamReader(
                            httpConnection.getInputStream()));
                } else {
                    breader = new BufferedReader(new InputStreamReader(
                            httpConnection.getErrorStream()));
                }

                String line = null;
                while ((line = breader.readLine()) != null) {
                    result.append(line);
                }
                httpConnection.disconnect();
                httpConnection = null;
                fetchSuccess = true;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (httpConnection != null) {
                    httpConnection.disconnect();
                    httpConnection = null;
                }
            }
            retry++;
        }
        return result.toString();
    }

    protected String appendGetParm(String orgUrl, String argName, String argValue) {
        String result = orgUrl;
        try {
            if (orgUrl.contains("?")) {
                result += "&" + argName + "=" + URLEncoder.encode(argValue, "utf-8");
            } else {
                result += "?" + argName + "=" + URLEncoder.encode(argValue, "utf-8");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

}
